{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ANN-SoLo profiling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import io\n",
    "import os\n",
    "import pstats\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.ticker as mticker\n",
    "import seaborn as sns\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plot styling\n",
    "plt.style.use(['seaborn-white', 'seaborn-paper'])\n",
    "plt.rc('font', family='serif')\n",
    "sns.set_palette('Set1')\n",
    "sns.set_context('paper', font_scale=1.3)    # single-column figure"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "prof_dir = '../../data/processed/iprg2012/profiling'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def extract_cum_time(stats, stream, func):\n",
    "    stats.print_stats(func)\n",
    "    stream.seek(0)\n",
    "    return float(stream.read().strip().split('\\n')[-1].split()[3])\n",
    "\n",
    "def process_prof(filename, version=2):\n",
    "    stream = io.StringIO()\n",
    "    stats = pstats.Stats(filename, stream=stream)\n",
    "\n",
    "    mode = 'Brute-force' if 'bf' in filename else 'ANN-SoLo'\n",
    "    precursor_tol_mass = 20 if 'std' in filename else 300\n",
    "    precursor_tol_mode = 'ppm' if 'std' in filename else 'Da'\n",
    "    prof = {'mode': mode,\n",
    "            'precursor_tol_mass': precursor_tol_mass,\n",
    "            'precursor_tol_mode': precursor_tol_mode,\n",
    "            'libio': extract_cum_time(stats, stream, 'get_spectrum'),\n",
    "            'rank': extract_cum_time(stats, stream, 'get_best_match'),\n",
    "            'version': version}\n",
    "    total = extract_cum_time(stats, stream, 'builtins.exec')\n",
    "    select_key = ('_get_library_candidates'\n",
    "                  if version == 2 else '_filter_library_candidates')\n",
    "    prof['select'] = (extract_cum_time(stats, stream, select_key)\n",
    "                      - prof['libio'])\n",
    "    prof['other'] = total - prof['select'] - prof['rank'] - prof['libio']\n",
    "    \n",
    "    return prof"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "profiling = [process_prof(\n",
    "    os.path.join(prof_dir, 'ann_oms_shifted_old.prof'), 1)]\n",
    "for filename in ['bf_std.prof', 'bf_oms_shifted.prof',\n",
    "                 'ann_oms_shifted.prof']:\n",
    "    profiling.append(process_prof(os.path.join(prof_dir, filename)))\n",
    "\n",
    "profiling = pd.DataFrame(profiling)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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xMbGFmhxIiIi1sSsUN2wYQNLlizB29sbAE9PT2bMmKGp30RERG5iVqja2dlRpkyZHG0VK1bEMIwCKUpERMQamRWq2dnZuQ71xsbGkp2dXSBFiYiIWCOzLlQaMmQIXbt21S01IiIit2BWqNatW5c1a9awevVqfv/9d91SIyIikgezb6mpUKECb731VkHWIiIiYtUs8/BeERERUaiKiIhYikJVRETEQu44VG/MVyoiIiI5mRWq6enpBAcH4+3tTadOnUhKSqJ79+6cPXu2oOsTERGxGmaFalBQEGlpaUyfPh03NzdcXV0ZPnw4QUFBBV1xSOH7AAAdWUlEQVSfiIiI1TArVE+dOsX48eN57rnnsLOzA+Dpp5/m6tWrBVqciIiINTErVDMyMsjMzMzRlpmZyZUrVwqkKBEREWtk1sMffHx86Nq1Ky+//DLJyclERUWxatUqGjduXND1iYiIWA2zQnXQoEE4ODiwcOFCzp07x2effUaXLl3o06dPQdcnIiJiNcwK1SJFitCvXz/69euXo11Tv4mIiPztnh7+0KtXL0vVISIiYvXMGqlGR0czceJETp8+TVZWFnB9lGpjY1OgxYmIiFgTs0J13LhxvPfee3h6elKs2PWXGIaBn59fgRYnIiJiTcwK1SpVqtC6detc7WFhYRYvSERExFqZdU61Z8+eLFmyhLi4OBISEkz/DRkypKDrExERsRpmjVTj4+MJCQnJ9QQlnVMVERH5m1mhGhkZyeLFi/H09KRo0aKm9n/eYiMiIvIwMytUq1evjpeXV652f39/ixckIiJircwK1dq1axMQEECzZs1wdnY2tY8bN46oqKgCK05ERMSamBWqU6dOxc3Nje3bt+do//PPPwukKBEREWtkVqg2bNiQmTNn5mp/9913LV6QiIiItTLrlpq8AhX0mEIREZGb5TtSvXTpEiVLlgRg9+7deW6jc6oiIiJ/yzdU27dvz+rVqylZsiRvvvkmpUuXzjUrjc6pioiI/C3fUN24cSN2dnYANG/ePM9HElr6nOratWsZMmQImzZtwt3dnczMTIKCgsjMzOTSpUv4+PjQrVs34PpD/levXo29vT3e3t507twZgJiYGJYuXcrEiRMtWpuIiMjt5BuqNwIV4O233861fsGCBRYN1XPnzrFu3bocbYsWLSIjI4OQkBAyMjJo164d3t7eeHp6MnXqVBYsWICTkxNt2rShc+fOpKenM2XKFCIiIixWl4iIiLnMulBp3Lhxudoee+wxRowYYZEiDMNg7NixufYXFRVFs2bNgOsh36hRI1asWAGAk5MTSUlJpKWlYWtrC0B4eDjdu3fH1dXVInWJiIjciVveUpOQkABARkYGv//+e45zqpUqVSIlJcUiRSxYsIAXXniBcuXK5WiPj4/Hzc3NtOzm5sahQ4cACAwMJDIyEoDg4GAOHz7MyZMnad68OQEBATg4ODB48GAcHR0tUqOIiMjt3DJUW7RoYXpofvPmzXOsc3Jy4o033rjnAo4ePcqRI0eYMGHCHb2uWrVqBAcHA5CVlUWfPn2YOHEi/fr1Y+nSpWzevJlZs2YxdOjQPF8fHh6uw8QiImJRtwzV2NhYAHr37s38+fMLpICNGzeSnZ1NQECAqS00NJRatWrh7u5OYmKiqT0xMRF3d/dc+4iMjKR9+/bY2tri5OREiRIl8PLyYtWqVfm+r6+vL76+vjnaPDw8LPCJRETkYWXWE5UKKlABBg4cmGP5yy+/ZOjQoaarf7du3UqbNm3IyMhg+/btua5CPnHiBDExMcyePZusrCxSU1MBuHDhAuXLly+wukVERP7JrFC9H44cOcKyZcuA64dmO3ToQI8ePRgzZgwjRowgJSWF3r17U6NGDdNrDMMgODiYwMBAbGxssLW1pWfPnowZM4aUlBRNoi4iIveVjfHPJzo8xDw8PIiLiyvUGjqsbFeo7/8g+LrTmsIuodA1CFxf2CUUup2jWxd2CYVOfw+s7++BWbfUiIiIyO0pVEVERCzErFC9du0a8+fP56WXXqJDhw4kJSXh5+fHpUuXCro+ERERq2FWqIaGhvL999/Tu3dvihcvjqurK23atMlxG4yIiMjDzqxQ3bt3L3PmzOG///0vxYsXB+CFF17g4sWLBVqciIiINTErVLOzs01PVrrZlStXLF6QiIiItTLrPlUvLy8GDhzIa6+9xuXLl9m1axfLly/n6aefLuj6RERErIZZI9UPPviAMmXKMHjwYA4dOsRbb72Fk5MT77//fkHXJyIiYjXMGqkeP36cjz/+mMDAQJKTkylVqlSeh4NFREQeZmaNVN9991327NmDjY0Nrq6uClQREZE8mBWqjo6O/PTTT7z55pvMnDmTc+fOFXRdIiIiVsesw78RERGmKdd2795NWFgYqamptG3blrZt2xZogSIiItbCrJHqzc/cd3BwwN7enp07dzJ16tQCK0xERMTamDVSHTJkCB06dOCrr77i7NmztGnThk8//ZQ6deoUdH0iIiJWw6xQ/eWXX3BwcKB37960bduWEiVKFHRdIiIPvfP7Bhd2CYWvU2EXcGfMCtWuXbsSGBhY0LWIiIhYNbPOqeYXqAMGDLBoMSIiItYs35HqsGHDGD16NI6Ojjz//PO51huGwZ9//lmgxYmIiFiTfEO1WbNmODg4AODs7MzIkSNzrDcMg/HjxxdsdSIiIlYk31Bt37696eexY8fi5eWVY/25c+cYO3ZswVUmIiJiZcw6pzp37txcbaGhocyZM8fiBYmIiFgrs0L1woULudpCQkKIj4+3eEEiIiLW6pa31LzxxhvY2NgQGxtLz549c6y7cuVKjictiYiIPOxuGaqdO3cGYNasWbz88ss51jk5OdGgQYOCq0xERMTK3DJUbwRp2bJladiw4X0pSERExFqZdU41v0D18/OzaDEiIiLWzKzHFCYlJTF58mR+/vlnLl++bGpPTEwssMJERESsjVmhOnr0aJo0acLhw4cZP348WVlZfP/992RkZBR0fSIiIlbDrMO/ly5d4r///S/Ozs7Uq1ePhg0bMnz4cI1URUREbmJWqN5w7do10z2rqampxMXFFUhRIiIi1sisw7/ly5fnq6++4oUXXqBjx454eXkRFxdHvXr1Cro+ERERq2FWqAYGBpKVlYWjoyOurq7s37+fxo0b8/rrrxd0fSIiIlbDrFC1t7fH3t4egA4dOtChQwcANmzYQKtWrQquOhERESuSb6iuXLnyti+eNWuWQlVEROT/yzdUx44di6en5y1frKt/RURE/pZvqLZs2fK2k5CPGDHC4gWJiIhYq3xDNa9AvXjxIomJiVStWhXDMG4buuZIS0tjwoQJFClSBDs7O06cOMGgQYOoVasWmZmZBAUFkZmZyaVLl/Dx8aFbt24AREdHs3r1auzt7fH29jY9/D8mJoalS5cyceLEe65NRETkTph1oVJycjIjR45ky5YtuLu7s3z5cnr06MGkSZNue4jYnH2npKQQFhYGwObNmxk0aBDbt29n0aJFZGRkEBISQkZGBu3atcPb2xtPT0+mTp3KggULcHJyok2bNnTu3Jn09HSmTJlCRETEPdUkIiJyN8x6+MPHH3+M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\n",
      "text/plain": [
       "<Figure size 504x311.496 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "width = 7\n",
    "height = width / 1.618    # golden ratio\n",
    "fig, ax = plt.subplots(figsize=(width, height))\n",
    "\n",
    "profiling_v2 = profiling[profiling['version'] == 2]\n",
    "profiling_bar = profiling_v2[['select', 'rank', 'libio', 'other']]\n",
    "# Convert to relative time percentages.\n",
    "profiling_bar = profiling_bar.div(profiling_bar.sum(axis=1), axis=0) * 100\n",
    "profiling_bar.columns = ['Candidate selection', 'Candidate ranking', 'I/O',\n",
    "                         'Other']\n",
    "\n",
    "profiling_bar.plot.bar(ax=ax, stacked=True)\n",
    "\n",
    "ax.set_ylabel('Relative time consumption')\n",
    "\n",
    "xtick_labels = (profiling_v2['mode'].map(str) + '\\n' +\n",
    "                profiling_v2['precursor_tol_mass'].map(str) + ' ' +\n",
    "                profiling_v2['precursor_tol_mode'].map(str))\n",
    "ax.set_xticklabels(xtick_labels, rotation='horizontal')\n",
    "\n",
    "ax.yaxis.set_major_formatter(mticker.PercentFormatter())\n",
    "\n",
    "ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15), ncol=2)\n",
    "\n",
    "sns.despine()\n",
    "\n",
    "plt.savefig('profiling_rel.pdf', dpi=300, bbox_inches='tight')\n",
    "plt.show()\n",
    "plt.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 504x311.496 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "width = 7\n",
    "height = width / 1.618    # golden ratio\n",
    "fig, ax = plt.subplots(figsize=(width, height))\n",
    "\n",
    "profiling_bar = (profiling[profiling['mode'] == 'ANN-SoLo']\n",
    "                 [['select', 'rank', 'libio', 'other']])\n",
    "profiling_bar.columns = ['Candidate selection', 'Candidate ranking', 'I/O',\n",
    "                         'Other']\n",
    "# Convert time to minutes.\n",
    "profiling_bar = profiling_bar.div(60, axis=0)\n",
    "\n",
    "profiling_bar.plot.bar(ax=ax, stacked=True)\n",
    "\n",
    "ax.set_xticklabels(['ANN-SoLo v1', 'ANN-SoLo v2'], rotation='horizontal')\n",
    "ax.set_ylabel('Runtime (min)')\n",
    "\n",
    "h, l = ax.get_legend_handles_labels()\n",
    "ax.legend(h[::-1], l[::-1], loc='upper right')\n",
    "\n",
    "sns.despine()\n",
    "\n",
    "plt.savefig('profiling_abs.pdf', dpi=300, bbox_inches='tight')\n",
    "plt.show()\n",
    "plt.close()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
